#region Using References

using System;
using Beaker.OpenCube.Mapping;

#endregion

namespace Beaker.OpenCube.Game.Converters
{
	/// <summary>
	/// Converter to convert Unix epoch values to .NET DateTime
	/// </summary>
	public class UnixDateTimeConverter
		: IValueConverter
	{
		/// <summary>
		/// The unix epoch
		/// </summary>
		public static readonly DateTime UnixEpoch = new DateTime( 1970, 1, 1, 0, 0, 0, DateTimeKind.Utc );

		/// <summary>
		/// Convert from NBT Unix epoch to a local DateTime value.
		/// </summary>
		/// <param name="nbtValue">The NBT Unix epoch to convert to a local value.</param>
		/// <returns>
		/// A DateTime value.
		/// </returns>
		public object FromNbtToLocal( object nbtValue )
		{
			if( nbtValue is long )
			{
				long unixTicks = (long)nbtValue * 10000;

				// conver to UTC base on ticks sinds 1970
				var utcDateTime = new DateTime( UnixEpoch.Ticks + unixTicks, DateTimeKind.Utc );

				// and convert to local
				return utcDateTime.ToLocalTime();
			}

			throw new InvalidOperationException( "Can only convert long (unix epoch) to DateTime" );
		}

		/// <summary>
		/// Convert from local DateTime value to a NBT Unix epoch.
		/// </summary>
		/// <param name="localValue">The local DateTime value to convert to a NBT Unix epoch.</param>
		/// <returns>
		/// A NBT Unix epoch.
		/// </returns>
		public object FromLocalToNbt( object localValue, Type targetType )
		{
			if( localValue is DateTime && targetType == typeof( long ) )
			{
				var dateTime = (DateTime)localValue;

				// conver to UTC base on ticks sinds 1970
				long ticks = dateTime.Ticks;
				ticks -= UnixEpoch.Ticks;

				// and convert to local
				return ticks;
			}

			throw new InvalidOperationException( "Can only convert DateTime to long (unix epoch)" );
		}
	}
}